import { MsgCall } from "tsrpc";
import { Singleton } from "../../shared/framework/base/Singleton";
import { GameRoom } from "./GameRoom";
import { MsgCJoinRoom } from "../../shared/protocols/battle/MsgCJoinRoom";
import { server } from "../..";
import { MsgCBuyTower } from "../../shared/protocols/battle/MsgCBuyTower";
import { EArea } from "../../shared/common/Enum";
import { GameUser } from "./GameUser";
import { MsgCSellTower } from "../../shared/protocols/battle/MsgCSellTower";
import { MsgCMergeTower } from "../../shared/protocols/battle/MsgCMergeTower";
import { MsgCExchangePos } from "../../shared/protocols/battle/MsgCExchangePos";
import { MsgCDrawCard } from "../../shared/protocols/battle/MsgCDrawCard";
import { MsgCUpgrade } from "../../shared/protocols/battle/MsgCUpgrade";

/** 游戏管理 */
export class GameManager extends Singleton {

    public static get Ins() {
        return this.GetInstance<GameManager>()
    }
    /** 当前房间 */
    curRoomId: number = 0
    nextRoomId: number = 0
    rooms: { [key: number]: GameRoom } = {}
    users: { [userId: number]: GameUser } = {}

    init() {
        this.listenConn()
        this.listenDisconn()
    }

    /** 监听链接 */
    listenConn() {

        server.listenMsg('battle/CJoinRoom', call => {
            this.joinRoom(call)
        })

        server.listenMsg('battle/CExchangePos', call => {
            this.exchangePos(call)
        })

        server.listenMsg('battle/CBuyTower', call => {
            this.buyTower(call)
        })

        server.listenMsg('battle/CMergeTower', call => {
            this.mergeTower(call)
        })

        server.listenMsg('battle/CSellTower', call => {
            this.sellTower(call)
        })

        server.listenMsg('battle/CDrawCard', call => {
            this.drawCard(call)
        })

        server.listenMsg('battle/CUpgrade', call => {
            this.upgrade(call)
        })

    }

    /** 监听断开 */
    listenDisconn() {
        server.flows.postDisconnectFlow.push(v => {
            let userId = 0
            for (const key in this.users) {
                if (this.users[key].conn?.id == v.conn.id) {
                    userId = this.users[key].data.userId
                    break
                }
            }
            const user = this.users[userId]
            if (user) {
                console.warn(user.data.userId + ' 断开连接')
                user.disconn()
                this.rooms[user.data.roomId].disconn(userId)
                return v
            }
        })
    }

    /** 获取用户 */
    getUserById(userId: number) {
        return this.users[userId]
    }

    /** 获取房间 */
    getRoomById(roomId: number) {
        return this.rooms[roomId]
    }

    /** 加入房间 */
    joinRoom(call: MsgCall<MsgCJoinRoom, any>) {
        const userId = call.msg.id
        const roomId = this.users[userId]?.data.roomId || 0
        const room = this.rooms[roomId]

        if (room) {
            this.users[userId].joinRoom(room.gameData.roomId, call)
            room.userRejoin()
        } else {
            if (this.curRoomId) {
                const area = EArea.up
                const user = new GameUser(area, call)
                const room = this.rooms[this.curRoomId]
                room.userJoin(user)

                user.joinRoom(room.gameData.roomId, call)
                this.users[userId] = user

                this.curRoomId = 0
            } else {
                const area = EArea.down
                const roomId = ++this.nextRoomId
                const room = new GameRoom(roomId)

                const user = new GameUser(area, call)
                user.joinRoom(roomId, call)

                room.userJoin(user)

                this.rooms[roomId] = room
                this.users[userId] = user

                this.curRoomId = roomId
            }
        }

    }

    /** 塔交换位置 */
    exchangePos(call: MsgCall<MsgCExchangePos, any>) {
        const index1 = call.msg.index1
        const index2 = call.msg.index2
        const userId = Number(call.msg.id)

        const user = this.getUserById(Number(userId))
        const room = this.getRoomById(user.data.roomId)
        room.exchangePos(index1, index2, user.data.area)
    }

    /** 购买防御塔 */
    buyTower(call: MsgCall<MsgCBuyTower, any>) {
        const user = this.getUserById(call.msg.id)
        user.buyTower()
    }

    /** 抽卡 */
    drawCard(call: MsgCall<MsgCDrawCard, any>) {
        const user = this.getUserById(call.msg.id)
        user.drawCard(call)
    }

    /** 用户强化 */
    upgrade(call: MsgCall<MsgCUpgrade, any>) {
        const user = this.getUserById(call.msg.id)
        user.upgrade(call.msg.type)
    }

    /** 出售防御塔 */
    sellTower(call: MsgCall<MsgCSellTower, any>) {
        const userId = Number(call.msg.id)
        const towerId = call.msg.towerId
        const user = this.getUserById(Number(userId))
        const room = this.getRoomById(user.data.roomId)
        room.sellTower(userId, towerId)
    }

    /** 合成防御塔 */
    mergeTower(call: MsgCall<MsgCMergeTower, any>) {
        const userId = Number(call.msg.id)
        const indexX = call.msg.indexX
        const indexY = call.msg.indexY
        const user = this.getUserById(Number(userId))
        const room = this.getRoomById(user.data.roomId)
        room.mergeTower(user.data.area, indexX, indexY)
    }

}